package com.alan.demo.utilt.sql;

import com.alibaba.druid.pool.DruidPooledPreparedStatement;
import com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.logging.jdbc.PreparedStatementLogger;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
import java.sql.Statement;
import java.util.Properties;

@Intercepts({@Signature(
        type = StatementHandler.class,
        method = "parameterize",
        args = {Statement.class}
)})
public class SqlInterceptor implements Interceptor {

    public static final String pkg = "com.mysql.cj.jdbc.ClientPreparedStatement: ";

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        Object result = invocation.proceed();
        if (SqlUtils.isOpen()) {
            Statement arg = (Statement) invocation.getArgs()[0];
            String sql;
            if (Proxy.isProxyClass(arg.getClass())) {
                MetaObject metaObject = SystemMetaObject.forObject(arg);
                PreparedStatementLogger h = (PreparedStatementLogger) metaObject.getValue("h");
                DruidPooledPreparedStatement preparedStatement = (DruidPooledPreparedStatement) h.getPreparedStatement();
                PreparedStatementProxyImpl statement = (PreparedStatementProxyImpl) preparedStatement.getStatement();
                Field field = statement.getClass().getDeclaredField("statement");
                field.setAccessible(true);
                sql = field.get(statement).toString().replaceAll(pkg, "");
            } else {
                sql = arg.toString().replaceAll(pkg, "");
            }
            SqlUtils.addSql(sql);
        }
        return result;

    }

    @Override
    public Object plugin(Object o) {
        return Plugin.wrap(o, this);
    }

    @Override
    public void setProperties(Properties properties) {
    }

}